home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Compendium Deluxe 2
/
LSD and 17bit Compendium Deluxe - Volume II.iso
/
a
/
prog
/
asmsrc
/
thesource-7.lha
/
Source
/
DefFunc.lha
/
DefFunc
/
defunc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-12-14
|
14KB
|
497 lines
/*********************************************************
*
* Copyright (c) 1993 Ke Jin
*
* Permission to use, copy, modify, and distribute
* this software and its documentation without fee
* is granted, provided that the author's name and
* this copyright notice are retained.
*
* -----------------------------------------------------
*
* defunc.c -- defunc high level module
*
* public function : dfopen();
* dfclose();
* dfcloseall();
*
* private function : getfreehdl();
* tdfopen();
* getexprbody();
* getexprname();
* getexprset();
* isfnctexpr();
*
* brkbalance();
*
* hdl00() to hdl31();
*
* private variable : tr_arr[];
* : hdl_arr[];
*
*********************************************************/
#include <stdio.h>
#include <malloc.h>
#include <ctype.h>
#include <string.h>
#include "dfctree.h"
#include "dfcsymtable.h"
#include "defunc.h"
#ifdef __cplusplus /* for c++ */
extern "C" {
#endif
#define MAXHANDLE 32
typedef Node* Tree;
typedef double (*FP)();
#if NeedFunctionPrototypes
static Tree tr_arr[MAXHANDLE]; /* predeclare static member */
static FP hdl_arr[MAXHANDLE]; /* predeclare static member */
static char* getexprbody(char* inputstr);
static char* getexprname(char* inputstr);
static char* getarguset(char* inputstr, int argidx);
static int isfnctexpr(char* inputstr);
static int brkbalance(char* inputstr);
#else
extern Tree tr_arr[MAXHANDLE]; /* predeclare static member */
extern FP hdl_arr[MAXHANDLE]; /* predeclare static member */
extern char* getexprbody();
extern char* getexprname();
extern char* getarguset();
extern int isfnctexpr();
extern int brkbalance();
#endif /* predeclare private function */
#if NeedFunctionPrototypes
static int getfreehdl(void)
#else
static int getfreehdl()
#endif
/* return the index of free handle on success. return -1 on fail */
{
int i;
for(i=0;i<MAXHANDLE;i++)
{
if(tr_arr[i]==(Node*)0) return i;
}
return -1; /* if no free handle */
};
#if NeedFunctionPrototypes
static double (*tdfopen(char* exprbody))(double x, double y)
#else
static double (*tdfopen(exprbody))()
char* exprbody;
#endif
/* Only accept expression body. Return handle function or NULL */
{
int i, size;
if(brkbalance(exprbody)!=0)
{
exparserror = "unbalanced ( ) in expression";
return 0;
}
if((i=getfreehdl())==-1) return 0; /* no free handle */
size = exparse(exprbody);
if(size<=0) return 0;
tr_arr[i] = (Node*)malloc(sizeof(Node)*size);
if(tr_arr[i]==0)
{
exparserror = "fail to alloc memory for new parse tree";
return 0;
}
getparsetree(tr_arr[i]);
reduce(tr_arr[i], 0);
return hdl_arr[i];
};
#if NeedFunctionPrototypes
double (*dfopen(char* expr))(double x, double y)
#else
double (*dfopen(expr))()
char* expr;
#endif
/* Accept full expression as well as expression
* body. Return handle function or NULL */
{
double (*fnctptr)();
char* exprbody;
char* exprname;
char *arg1, *arg2;
exparserror = 0;
if(brkbalance(expr)!=0)
{
exparserror = "unbalanced ( ) in expression";
return 0;
}
exprbody = getexprbody(expr);
exprname = getexprname(expr);
arg1 = getarguset(expr, 1);
arg2 = getarguset(expr, 2);
if(nameargu(arg1, arg2)==-1)
{
exparserror = "error on reset argument";
return 0;
}
fnctptr = tdfopen(exprbody);
if(exprname!=0)
{
if(arg1!=0||isfnctexpr(expr))
{
namefnct(exprname, fnctptr);
}
else if(fnctptr!=0)
{
namecnst(exprname, fnctptr());
}
}
return fnctptr;
};
#if NeedFunctionPrototypes
int dfclose(double (*fnctptr)())
#else
int dfclose(fnctptr)
double (*fnctptr)();
#endif
/* close a dynamic function(getten from dfopen) if it not on
* the global name-function association table. On success,
* return 0. On fail return -1
*/
{
int i;
if(getsym(getfnctname(fnctptr))!=0) return -1;
/* function still on symbol table can't be closed */
for(i=0;i<MAXHANDLE;i++)
{
if(fnctptr==hdl_arr[i])
{
if(tr_arr[i]!=0) free(tr_arr[i]);
tr_arr[i]=0;
return 0; /* success */
}
}
return -1; /* fail to close */
};
#if NeedFunctionPrototypes
int dfcloseall(void)
#else
int dfcloseall()
#endif
/* close all (not on the association table) dynamic functions
* Return the total number of handler freed by this calling.
*/
{
int i, j;
for(i=0, j=0; i<MAXHANDLE; i++)
{
if(tr_arr[i]!=0) /* unfreed handle */
{
if(dfclose(hdl_arr[i])==0) /* success */
{
tr_arr[i]=0;
j++;
}
}
}
return j;
};
#if NeedFunctionPrototypes
static char* getexprbody(char* str)
#else
static char* getexprbody(str)
char* str;
#endif
/* extract the expression body from an input string */
{
int i;
for(i=0;i<strlen(str);i++)
{
if(str[i]=='=') return str+i+1;
/* found '=' in str, substring after '=' be returned */
}
return str; /* no '=' be found, then return str itself */
};
#if NeedFunctionPrototypes
static char* getexprname(char* str)
#else
static char* getexprname(str)
char* str;
#endif
/* extract the expression title from an input string */
{
int i, j=0, len;
static char* name;
for(i=0; i<strlen(str);i++)
{
if(str[i]=='=') break;
/* if no '=' be found, then it's a anonymous expression */
}
if(i==strlen(str)) return 0;
len = i;
name = (char*)malloc(len*sizeof(char));
if(name == 0)
{
perror("malloc in getarguset()");
exit(1);
}
for(i=0; i<len; i++)
{
if(isalnum(str[i]))
{
name[j] = str[i];
j++;
}
else break;
}
name[j]= '\0';
if(strlen(name)==0) return 0;
return name;
};
#if NeedFunctionPrototypes
static char* getarguset(char* str, int argidx)
#else
static char* getarguset(str, argidx)
char* str;
int argidx;
#endif
/* extract an argument name from input string */
{
int i, j=0, len;
char c;
static char *name1;
static char *name2;
for(i=0; i<strlen(str); i++)
{
if(str[i]=='=') break;
/* if no '=' be found, then it's a anonymous expression */
}
if(i==strlen(str)) return 0;
len=i;
/* len is the length of substring (those part in front of '=') */
for(i=0; i<len; i++)
{
if(argidx==1)
{
name1 = (char*)malloc(len*sizeof(char));
if(name1 == 0)
{
perror("malloc in getarguset()");
exit(1);
}
if(str[i] == '(') /* skim over the expr name */
{
for(i=i+1;i<len;i++)
{
c = str[i];
if(j==0&&(c==' '||c=='\t')) continue;
if(c!=','&&c!=')'&&c!='='&&c!=' '&&c!='\t')
{
name1[j]=c;
j++;
}
else break;
}
name1[j]='\0';
if(strlen(name1)==0) return 0;
return name1;
}
}
if(argidx==2)
{
name2 = (char*)malloc(len*sizeof(char));
if(name2 == 0)
{
perror("malloc in getarguset()");
exit(1);
}
if(str[i] == ',')
/* skim over the expr and 1st argu names */
{
for(i=i+1;i<len;i++)
{
c=str[i];
if(j==0&&(c==' '||c=='\t')) continue;
if(c!=','&&c!=')'&&c!='='&&c!=' '&&c!='\t')
{
name2[j]=str[i];
j++;
}
else break;
}
name2[j]='\0';
if(strlen(name2)==0) return 0;
return name2;
}
}
}
return 0;
};
#if NeedFunctionPrototypes
static int isfnctexpr(char* expression)
#else
static int isfnctexpr(expression)
char* expression;
#endif
/* to see the title is in "name(...)=" form or in "name=" form */
{
int i, tag=0;
char c;
if(expression==0) return 0;
for(i=0; i<strlen(expression); i++)
{
c=expression[i];
if(c=='(') tag=1;
if(c=='=') return tag;
}
return tag;
};
#if NeedFunctionPrototypes
static int brkbalance(char* expression)
#else
static int brkbalance(expression)
char* expression;
#endif
/* check the balance of '(' and ')'. Return 0 on balance */
{
int i,j;
char c;
for(i=0, j=0;i<strlen(expression);i++)
{
c = expression[i];
if(c=='(') j++;
if(c==')') j--;
}
return j;
};
/* ------------------------- private members ------------------------ */
static Tree tr_arr[MAXHANDLE];
#if NeedFunctionPrototypes
static double hdl00(double x,double y){return evaluate(tr_arr[ 0],0,x,y);};
static double hdl01(double x,double y){return evaluate(tr_arr[ 1],0,x,y);};
static double hdl02(double x,double y){return evaluate(tr_arr[ 2],0,x,y);};
static double hdl03(double x,double y){return evaluate(tr_arr[ 3],0,x,y);};
static double hdl04(double x,double y){return evaluate(tr_arr[ 4],0,x,y);};
static double hdl05(double x,double y){return evaluate(tr_arr[ 5],0,x,y);};
static double hdl06(double x,double y){return evaluate(tr_arr[ 6],0,x,y);};
static double hdl07(double x,double y){return evaluate(tr_arr[ 7],0,x,y);};
static double hdl08(double x,double y){return evaluate(tr_arr[ 8],0,x,y);};
static double hdl09(double x,double y){return evaluate(tr_arr[ 9],0,x,y);};
static double hdl10(double x,double y){return evaluate(tr_arr[10],0,x,y);};
static double hdl11(double x,double y){return evaluate(tr_arr[11],0,x,y);};
static double hdl12(double x,double y){return evaluate(tr_arr[12],0,x,y);};
static double hdl13(double x,double y){return evaluate(tr_arr[13],0,x,y);};
static double hdl14(double x,double y){return evaluate(tr_arr[14],0,x,y);};
static double hdl15(double x,double y){return evaluate(tr_arr[15],0,x,y);};
static double hdl16(double x,double y){return evaluate(tr_arr[16],0,x,y);};
static double hdl17(double x,double y){return evaluate(tr_arr[17],0,x,y);};
static double hdl18(double x,double y){return evaluate(tr_arr[18],0,x,y);};
static double hdl19(double x,double y){return evaluate(tr_arr[19],0,x,y);};
static double hdl20(double x,double y){return evaluate(tr_arr[20],0,x,y);};
static double hdl21(double x,double y){return evaluate(tr_arr[21],0,x,y);};
static double hdl22(double x,double y){return evaluate(tr_arr[22],0,x,y);};
static double hdl23(double x,double y){return evaluate(tr_arr[23],0,x,y);};
static double hdl24(double x,double y){return evaluate(tr_arr[24],0,x,y);};
static double hdl25(double x,double y){return evaluate(tr_arr[25],0,x,y);};
static double hdl26(double x,double y){return evaluate(tr_arr[26],0,x,y);};
static double hdl27(double x,double y){return evaluate(tr_arr[27],0,x,y);};
static double hdl28(double x,double y){return evaluate(tr_arr[28],0,x,y);};
static double hdl29(double x,double y){return evaluate(tr_arr[29],0,x,y);};
static double hdl30(double x,double y){return evaluate(tr_arr[30],0,x,y);};
static double hdl31(double x,double y){return evaluate(tr_arr[31],0,x,y);};
#else
static double hdl00(x,y) double x,y; {return evaluate(tr_arr[ 0],0,x,y);};
static double hdl01(x,y) double x,y; {return evaluate(tr_arr[ 1],0,x,y);};
static double hdl02(x,y) double x,y; {return evaluate(tr_arr[ 2],0,x,y);};
static double hdl03(x,y) double x,y; {return evaluate(tr_arr[ 3],0,x,y);};
static double hdl04(x,y) double x,y; {return evaluate(tr_arr[ 4],0,x,y);};
static double hdl05(x,y) double x,y; {return evaluate(tr_arr[ 5],0,x,y);};
static double hdl06(x,y) double x,y; {return evaluate(tr_arr[ 6],0,x,y);};
static double hdl07(x,y) double x,y; {return evaluate(tr_arr[ 7],0,x,y);};
static double hdl08(x,y) double x,y; {return evaluate(tr_arr[ 8],0,x,y);};
static double hdl09(x,y) double x,y; {return evaluate(tr_arr[ 9],0,x,y);};
static double hdl10(x,y) double x,y; {return evaluate(tr_arr[10],0,x,y);};
static double hdl11(x,y) double x,y; {return evaluate(tr_arr[11],0,x,y);};
static double hdl12(x,y) double x,y; {return evaluate(tr_arr[12],0,x,y);};
static double hdl13(x,y) double x,y; {return evaluate(tr_arr[13],0,x,y);};
static double hdl14(x,y) double x,y; {return evaluate(tr_arr[14],0,x,y);};
static double hdl15(x,y) double x,y; {return evaluate(tr_arr[15],0,x,y);};
static double hdl16(x,y) double x,y; {return evaluate(tr_arr[16],0,x,y);};
static double hdl17(x,y) double x,y; {return evaluate(tr_arr[17],0,x,y);};
static double hdl18(x,y) double x,y; {return evaluate(tr_arr[18],0,x,y);};
static double hdl19(x,y) double x,y; {return evaluate(tr_arr[19],0,x,y);};
static double hdl20(x,y) double x,y; {return evaluate(tr_arr[20],0,x,y);};
static double hdl21(x,y) double x,y; {return evaluate(tr_arr[21],0,x,y);};
static double hdl22(x,y) double x,y; {return evaluate(tr_arr[22],0,x,y);};
static double hdl23(x,y) double x,y; {return evaluate(tr_arr[23],0,x,y);};
static double hdl24(x,y) double x,y; {return evaluate(tr_arr[24],0,x,y);};
static double hdl25(x,y) double x,y; {return evaluate(tr_arr[25],0,x,y);};
static double hdl26(x,y) double x,y; {return evaluate(tr_arr[26],0,x,y);};
static double hdl27(x,y) double x,y; {return evaluate(tr_arr[27],0,x,y);};
static double hdl28(x,y) double x,y; {return evaluate(tr_arr[28],0,x,y);};
static double hdl29(x,y) double x,y; {return evaluate(tr_arr[29],0,x,y);};
static double hdl30(x,y) double x,y; {return evaluate(tr_arr[30],0,x,y);};
static double hdl31(x,y) double x,y; {return evaluate(tr_arr[31],0,x,y);};
#endif
static FP hdl_arr[MAXHANDLE] ={
hdl00, hdl01, hdl02, hdl03, hdl04, hdl05, hdl06, hdl07,
hdl08, hdl09, hdl10, hdl11, hdl12, hdl13, hdl14, hdl15,
hdl16, hdl17, hdl18, hdl19, hdl20, hdl21, hdl22, hdl23,
hdl24, hdl25, hdl26, hdl27, hdl28, hdl29, hdl30, hdl31 };
#ifdef __cplusplus
} /* end for c++ */
#endif